<?php

class sfNumeroValidator extends sfValidator
{
  
  const DECIMAL_SEPARATOR = '.';
  
  public function execute(&$value, &$error)
  {
    $type = strtolower($this->getParameterHolder()->get('type'));
    $culture = $this->getContext()->getUser()->getCulture();
    $formatInfo = sfNumberFormatInfo::getInstance($culture);
    $value = str_replace($formatInfo->getGroupSeparator(),'',$value);
    $value = str_replace($formatInfo->getDecimalSeparator(),self::DECIMAL_SEPARATOR,$value);

    switch ($type)
    {
      case "decimal":
      case "float":
      {
        if ((string)(float)$value != $value)
        {
          $error = $this->getParameterHolder()->get('type_error');
          return false;
        }
        $value = (float) $value;
        break;
      }
      case "int":
      case "integer":
      {
        if ($value != (string)(int)$value)
        {
          $error = $this->getParameterHolder()->get('type_error');
          return false;
        }
        $value = (int) $value;
        break;
      }
    }
    $min = $this->getParameterHolder()->get('min');
    if ($min !== null && $value < $min)
    {
      $error = $this->getParameterHolder()->get('min_error');
      return false;
    }
    $max = $this->getParameterHolder()->get('max');
    if ($max !== null && $value > $max)
    {
      $error = $this->getParameterHolder()->get('max_error');
      return false;
    }
    return true;
  }

  /**
   * Initializes this validator.
   *
   * @param sfContext The current application context
   * @param array   An associative array of initialization parameters
   *
   * @return bool true, if initialization completes successfully, otherwise false
   */
  public function initialize($context, $parameters = null)
  {
    // initialize parent
    parent::initialize($context);

    // set defaults
    $this->getParameterHolder()->set('max',        null);
    $this->getParameterHolder()->set('max_error',  'Input is too large');
    $this->getParameterHolder()->set('min',        null);
    $this->getParameterHolder()->set('min_error',  'Input is too small');
    $this->getParameterHolder()->set('nan_error',  'Input is not a number');
    $this->getParameterHolder()->set('type',       'any');
    $this->getParameterHolder()->set('type_error', 'Input is not a number');

    $this->getParameterHolder()->add($parameters);

    // check user-specified parameters
    $type = strtolower($this->getParameterHolder()->get('type'));

    // array of allowed types
    $allowed_types = array('any', 'decimal', 'float', 'int', 'integer');

    if (!in_array(strtolower($type), $allowed_types))
    {
      // unknown type
      $error = 'Unknown number type "%s" in NumberValidator';
      $error = sprintf($error, $this->getParameterHolder()->get('type'));

      throw new sfValidatorException($error);
    }

    return true;
  }
}
